package com.flanz.apache.velocity.uimocker;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

/**
 * HTTPRequestHandler.
 * 
 * @author cf
 * 
 */
public class HTTPRequestHandler {
	private final static String SERVER_NAME = "Flanz Apache Velocity Mock System 0.9";

	public static void handleSocketConnection(Properties VM_APP_VARS,
			MimeTable mimeTable, String staticDir, String httpDocRoot, String macrosFileList,
			InputStream inputStream, OutputStream outputStream)
			throws IOException, Exception, FileNotFoundException {

		BufferedReader in = new BufferedReader(new InputStreamReader(
				inputStream));
		String fileName = "";
		String str = ".";
		File spoolFile = null;
		while (str != null && !"".equals(str)) {
			str = in.readLine();
			if (str != null && str.startsWith("GET ")) {
				System.out.println(str);
				fileName = str.split(" ")[1];
				// System.out.println("GET:"+ fileName);
				// remove arguments
				int indexOf = fileName.indexOf('?');
				if (indexOf != -1) {
					fileName = fileName.substring(0, indexOf);
				}
				// System.out.println(fileName);

				// default index.html ak. index.vm
				if (("".endsWith(fileName)) || ("/".equals(fileName))) {
					fileName = "/templates/template-index.vm";
				}

				// /template but no vm to rewrite
				if (fileName.startsWith("/template-")
						&& (fileName.endsWith(".vm") || fileName
								.endsWith(".html"))) {
					fileName = "/templates" + fileName;
					if (fileName.endsWith(".headless.html")) {
						fileName = StringUtils.replace(fileName, "headless.html", "headless.html.vm");	
					} else {
						fileName = StringUtils.replace(fileName, ".html", ".vm");	
					}
				}
				File staticFile = new File(httpDocRoot + fileName);
				if (staticFile.exists()) {
					spoolFile = staticFile;
				} else {
					spoolFile = new File(staticDir + fileName);
				}

			}
		}

		// Send the response
		if (spoolFile != null && spoolFile.exists()) {
			System.out.println("RESOLVE:" + spoolFile.getAbsolutePath());
			handleFile(VM_APP_VARS, mimeTable, staticDir, outputStream
					,macrosFileList ,fileName, spoolFile);

		} else {
			PrintWriter printWriter = new PrintWriter(outputStream);
			System.out.println("NOTFOUND:" + fileName);
			spoolDefaultHtml(printWriter, fileName);
		}
	}
	
	private static void handleFile(Properties VM_APP_VARS, MimeTable mimeTable,
			String staticDir, OutputStream outputStream, String macrosFileList, String fileName,
			File spoolFile) throws IOException, Exception,
			FileNotFoundException {
		if (fileName.endsWith(".vm") && fileName.startsWith("/templates/")) {
			// start VM
			ByteArrayOutputStream payLoadOutputStream = new ByteArrayOutputStream();
			VmGeneratorMain.generateHtml(VM_APP_VARS, staticDir, macrosFileList, fileName, 
					payLoadOutputStream);
			byte[] byteArray = payLoadOutputStream.toByteArray();
			ByteArrayInputStream payLoadInputStream = new ByteArrayInputStream(
					byteArray);
			sendFile("text/html", payLoadInputStream, outputStream,
					byteArray.length);

		} else {
			String mimeType = mimeTable.getMimeType(spoolFile);
			sendFile(mimeType, new FileInputStream(spoolFile), outputStream,
					spoolFile.length());

		}
	}
	private static void sendFile(String mimeType, InputStream inputStream,
			OutputStream outputStream, long size) throws IOException,
			FileNotFoundException {
		StringBuilder sb = new StringBuilder();
		sb.append("HTTP/1.0 200 OK\n");
		sb.append("Content-Type: " + mimeType);
		sb.append("\n");
		sb.append("Server: ");
		sb.append(SERVER_NAME);
		sb.append("\n");
		sb.append("Content-Length: ");
		sb.append(size);
		sb.append("\n");
		sb.append("\n");
		ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(sb
				.toString().getBytes());
		IOUtils.copy(byteArrayInputStream, outputStream);

		IOUtils.copy(inputStream, outputStream);
		outputStream.flush();
		IOUtils.closeQuietly(outputStream);
		IOUtils.closeQuietly(inputStream);
	}

	private static String HTML_404 = "\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL %s was not found on this server.</p>\n<hr>\n<address>%s at %s </address>\n</body></html>\n";
	private static void spoolDefaultHtml(PrintWriter out, String fileName) {

		InetAddress addr;
		try {
			addr = InetAddress.getLocalHost();
			out.println("HTTP/1.0 404 OK");
			out.println("Content-Type: text/html");
			out.println("Server: " + SERVER_NAME);
			// this blank line signals the end of the headers
			out.println("");
			// Send the HTML page
			String s = String.format(HTML_404, fileName, SERVER_NAME,
					addr.toString());
			out.println(s);
			out.flush();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
